From fee61634e8f3fec7c137f0d16478c64c7f355587 Mon Sep 17 00:00:00 2001 From: Jan Beulich Date: Thu, 6 Feb 2014 12:20:48 +0100 Subject: [PATCH] domctl: pause vCPU for context reads "Base" context reads already paused the subject vCPU when being the current one, but that special case isn't being properly dealt with anyway (at the very least when x86's fsgsbase feature is in use), so just disallow it. "Extended" context reads so far didn't do any pausing. While we can't avoid the reported data being stale by the time it arrives at the caller, this way we at least guarantee that it is consistent. Signed-off-by: Jan Beulich Acked-by: Keir Fraser Reviewed-by: Andrew Cooper Release-acked-by: George Dunlap --- xen/arch/x86/domctl.c | 7 +++++++ xen/common/domctl.c | 14 +++++--------- 2 files changed, 12 insertions(+), 9 deletions(-) diff --git a/xen/arch/x86/domctl.c b/xen/arch/x86/domctl.c index 432a180865..26635ffc47 100644 --- a/xen/arch/x86/domctl.c +++ b/xen/arch/x86/domctl.c @@ -819,7 +819,13 @@ long arch_do_domctl( if ( domctl->cmd == XEN_DOMCTL_get_ext_vcpucontext ) { + if ( v == current ) /* no vcpu_pause() */ + break; + evc->size = sizeof(*evc); + + vcpu_pause(v); + if ( is_pv_domain(d) ) { evc->sysenter_callback_cs = @@ -849,6 +855,7 @@ long arch_do_domctl( evc->vmce.mci_ctl2_bank1 = v->arch.vmce.bank[1].mci_ctl2; ret = 0; + vcpu_unpause(v); copyback = 1; } else diff --git a/xen/common/domctl.c b/xen/common/domctl.c index f237be4a77..7cf610a461 100644 --- a/xen/common/domctl.c +++ b/xen/common/domctl.c @@ -675,11 +675,9 @@ long do_domctl(XEN_GUEST_HANDLE_PARAM(xen_domctl_t) u_domctl) struct vcpu *v; ret = -EINVAL; - if ( op->u.vcpucontext.vcpu >= d->max_vcpus ) - goto getvcpucontext_out; - - ret = -ESRCH; - if ( (v = d->vcpu[op->u.vcpucontext.vcpu]) == NULL ) + if ( op->u.vcpucontext.vcpu >= d->max_vcpus || + (v = d->vcpu[op->u.vcpucontext.vcpu]) == NULL || + v == current ) /* no vcpu_pause() */ goto getvcpucontext_out; ret = -ENODATA; @@ -694,14 +692,12 @@ long do_domctl(XEN_GUEST_HANDLE_PARAM(xen_domctl_t) u_domctl) if ( (c.nat = xmalloc(struct vcpu_guest_context)) == NULL ) goto getvcpucontext_out; - if ( v != current ) - vcpu_pause(v); + vcpu_pause(v); arch_get_info_guest(v, c); ret = 0; - if ( v != current ) - vcpu_unpause(v); + vcpu_unpause(v); #ifdef CONFIG_COMPAT if ( !is_pv_32on64_vcpu(v) ) -- 2.30.2